/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 * Esta clase es la encargada de el juego de los paneles,hereda de jframe ya que es capaz
 * de incluirse en un jpanel con tal de poder ver en pantalla el juego y
 * el panel para interactuar en cuestion. En esta fase no fuimos capaces de
 * de juntar ambos tipos de juegos, queda pendiente.
 * Con el integer de tipomain se controla si es el primer player o el segundo.
 */
package edu.ieslaferreria.creditsintesis;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyListener;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;


import com.jme.input.InputSystem;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.JMECanvas;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jmex.awt.input.AWTKeyInput;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import edu.ieslaferreria.creditsintesis.logicgame.ActionStates;
import edu.ieslaferreria.creditsintesis.logicgame.ActionStatesHash1;
import edu.ieslaferreria.creditsintesis.logicgame.MeetingSituationLogic;
import edu.ieslaferreria.creditsintesis.logicgame.actions.RmiEvent;
import edu.ieslaferreria.creditsintesis.rmi.Client;
import edu.ieslaferreria.creditsintesis.rmi.EventChangePanel;
import edu.ieslaferreria.creditsintesis.rmi.EventChangePanelListener;
import edu.ieslaferreria.creditsintesis.rmi.EventConfiguracioListener;
import edu.ieslaferreria.creditsintesis.rmi.EventGoInListener;

import edu.ieslaferreria.creditsintesis.rmi.EventLocationListener;
import edu.ieslaferreria.creditsintesis.rmi.EventPanelsInteractionTwoPlayersListener;
import edu.ieslaferreria.creditsintesis.rmi.EventStateListener;
import edu.ieslaferreria.creditsintesis.rmi.EventGoInInteracction;
import edu.ieslaferreria.creditsintesis.rmi.EventIniciarInteraccion;
import edu.ieslaferreria.creditsintesis.rmi.EventIniciarInteraccionListener;
import edu.ieslaferreria.creditsintesis.rmi.GameEventInteracctionTwoPanels;
import edu.ieslaferreria.creditsintesis.rmi.Partida;
import edu.ieslaferreria.creditsintesis.rmi.Pont;
import edu.ieslaferreria.creditsintesis.rmi.PontImpl;
import edu.ieslaferreria.creditsintesis.rmi.PontServer;
import edu.ieslaferreria.creditsintesis.rmi.PontServerImpl;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
 *
 * @author Administrador
 * este es el panel que lleva el juego integrado.
 */
public class MeetingSituationScenePlayer1Rmi extends JFrame {

    private JPanel mainPanel;
    protected String DireccionRmi;
    protected int TipoMain;
    protected Partida partidaInt;
//    protected EventGoInListener GoInListener;
    protected EventPanelsInteractionTwoPlayersListener panelListener;
    protected EventChangePanelListener changePanelListener;
//    protected EventIniciarInteraccionListener IniciarPartidaIntListener;
    protected Client client;
    protected ActionStates actionStates; /*si da tiempo creare un actionstates para este juego y
     * adaptaremos la maquina de estados para el*/

    protected MeetingSituationLogic paneler;
    protected PontServer serverGame;
    
    protected static final Logger logger = Logger.getLogger(MeetingSituationScenePlayer1Rmi.class.getName());
    protected Canvas glCanvas;
    protected int width = 1024, height = 820;
    MeetingSituationLogic impl ;
    protected HashMap<String, Object> keys = new HashMap<String, Object>();

    public static void main(String args[]) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException, NotBoundException, MalformedURLException, RemoteException {
        try {
            ActionStates pruebaMainNOSERADETIPOHASHENREALIDAD = new ActionStatesHash1();
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            Toolkit.getDefaultToolkit().setDynamicLayout(true);
            JFrame.setDefaultLookAndFeelDecorated(true);

            MeetingSituationScenePlayer1Rmi app = new MeetingSituationScenePlayer1Rmi(pruebaMainNOSERADETIPOHASHENREALIDAD, 0, "player1");




        } catch (NotBoundException ex) {
            Logger.getLogger(MeetingSituationScenePlayer1Rmi.class.getName()).log(Level.SEVERE, null, ex);
        } catch (MalformedURLException ex) {
            Logger.getLogger(MeetingSituationScenePlayer1Rmi.class.getName()).log(Level.SEVERE, null, ex);
        } catch (RemoteException ex) {
            Logger.getLogger(MeetingSituationScenePlayer1Rmi.class.getName()).log(Level.SEVERE, null, ex);
        }

        // Signal to show properties dialog


    }

    @SuppressWarnings("empty-statement")
    public MeetingSituationScenePlayer1Rmi(ActionStates actsta, int tipoMain, String name) throws NotBoundException, MalformedURLException, RemoteException {
        super();

        this.TipoMain = tipoMain;
        if (this.TipoMain == 0) {
            this.DireccionRmi = "ServerImpl";
        }
        this.actionStates = actsta;
        setTitle("v. ferreria version");
        setBounds(100, 100, 760, 480);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        try {


            client = new Client(name);



            client.setListenerConfiguracio(new EventConfiguracioListener() {

                public void action(RmiEvent event) throws RemoteException {
                    //client.send(event);
                }
            });
            client.setListenerLocation(new EventLocationListener() {

                public void action(RmiEvent event) throws RemoteException {
                    //throw new UnsupportedOperationException("Not supported yet.");
                }
            });

            client.setListenerChangePanel(new EventChangePanelListener() {

                public void action(RmiEvent event) throws RemoteException {
                  
                    EventChangePanel ev = (EventChangePanel) event;
                    
                    changePanel(ev.getKindPanel(),ev.isResp(),"si hiciera falta alguna opcion aki(no suele)",ev.getPontPartidaInt());
                                       
                }
            });





            client.setListenerState(new EventStateListener() {

                public void action(RmiEvent event) throws RemoteException {
                    //throw new UnsupportedOperationException("Not supported yet.");
                }
            });

            client.setListenerIni(new EventIniciarInteraccionListener() {

                public void action(RmiEvent event) throws RemoteException {
                    EventIniciarInteraccion ev = (EventIniciarInteraccion) event;

                    Pont po = serverGame.addClient((Integer) ev.getId(), new PontImpl(client.getListener(), client.getNom()), client.getNom(), false);

                    //paneler.getPanels().get(serverGame.getPartidaGetPanelActivo(1)).setVisible(false);

                    //paneler.getSuitablePanelIni(ev.getKindPanel(), ev.isResp(), null, po);
                    changePanel(ev.getKindPanel(), ev.isResp(), null, po);

                    /*
                    client.setPontInterracction(po);
                    es necesario un puente de este tipo, si los paneles de cada player ya saben por el puente
                    que deben comunicarse ???? po en este caso*/
                }
            });

             client.setListenerPanel(new EventPanelsInteractionTwoPlayersListener() {

                public void action(RmiEvent event) throws RemoteException {
              GameEventInteracctionTwoPanels ev =  (GameEventInteracctionTwoPanels) event;

              paneler.getPanels().get(paneler.getCurrentPanelId()).update(ev.getOpcions(), (ArrayList<String>) ev.getAlias());

//              changePanel(ev.getNextPanel(),false,null,ev.getPont());
                }
            });



            if (this.TipoMain == 0) {
                serverGame = new PontServerImpl(actionStates, name);
                serverGame.setListener(client.getListener());
                PontServerImpl.registerToRegistry(this.DireccionRmi, serverGame, true);

                client.creaPartida(serverGame, false);

            } else {
//                DireccionRmi = System.getProperty("serverRmiUrl", "rmi://localhost/ServerImpl");
                DireccionRmi = System.getProperty("serverRmiUrl", "rmi://192.168.170.125/ServerImpl");
                serverGame = (PontServer) java.rmi.Naming.lookup(DireccionRmi);
            }
            client.setListenerGoin(new EventGoInListener() {

                /*listener de accio Goin*/
                public void action(RmiEvent evt) throws RemoteException {
                    EventGoInInteracction event = (EventGoInInteracction) evt;
//                    System.out.println(client.getNom());
//                    System.out.println("estoy pasando por el listener del goin felicidades!!!.");
                    /*PontServerImpl.registerToRegistry("ServerImplInt", serverGameInt, true);*/

                    //client.setKindPanel(MeetingSituationLogic.A_COMPETICIO);
                    Pont po;
                    /*crea partida interaccion*/
                    po = serverGame.createPartida(new PontImpl(client.getListener(), client.getNom()), client.getNom(), false);
                    /*como sabre que dos players son los que han chocado?????*/
                    /*pongo por ahora el 0 y el 1 para las pruebas*/



                    int cont = 0;
                    while (cont < event.getAliasPlayers().size()) {
                        /*meto todos los players que me llegan del evento en la partida actual*/

                        /*Añado el player*/
                        Pont pontClient = serverGame.getPartidaGetPontPlayer(0, event.getAliasPlayers().get(cont));
                        /*luego ya pondremos algo en lugar del 1 fijo*/
                        if (!event.getAliasPlayers().get(cont).equals(client.getNom())) {
                            System.out.println("Pasa por el evento iniciar interaccion...");
                            pontClient.send(new EventIniciarInteraccion(1, event.getKindPanel(), event.isResp(), event.getAliasPlayers(), po));
                        }

                        /*preparo el panel adecuado...luego el mainpanel se encarga de cojerlo unas
                         * lineas mas para abajo*/


                        cont++;
                    }/*partida 1 que es la recien creada partida interaccion*/
                    //paneler.getPanels().get(serverGame.getPartidaGetPanelActivo(1)).setVisible(false);

                    //paneler.getSuitablePanelIni(event.getKindPanel(), event.isResp(), null, po).setVisible(true);
                    changePanel(event.getKindPanel(), event.isResp(), null, po);

                }
            });
            /*listener que escucha lo que el otro panel le manda*/
            this.setPanelListener(new EventPanelsInteractionTwoPlayersListener() {

                public void action(RmiEvent event) throws RemoteException {
                    /*aqui deberia mirar que hacer para poder seguir
                    comunicacion entre los dos players mediante paneles...*/
                     GameEventInteracctionTwoPanels ev = (GameEventInteracctionTwoPanels) event;

                     paneler.getPanels().get(ev.getNextPanel()).update(ev.getOpcions(),null);
                    
                }
            });
            this.startGame();

            List<String> clients = new ArrayList();


            if (this.TipoMain == 0) {/*espera para el servidor*/
                //while(serverGame.getPartida(0).countClients()==1);

                clients = serverGame.getPartidaGetAlias(0);

            } else {/*espera para el cliente...que como siempre sera el segundo deberia de ser nula casi....*/

                serverGame.addClient(0, new PontImpl(client.getListener(), client.getNom()), client.getNom(), false);

            }




        } catch (RemoteException ex) {
            ex.printStackTrace();
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }







        // para probar antes de tocar nada creamos lista a partir del Array
//        if (client.getListenerGoin() != null) {
//            System.out.println(client.getNom());
//        }/*lanzamiwento del  goin*/
        Pont p = serverGame.getPartidaGetPontPlayer(0, client.getNom());
        client.setPont(p);                                 /*alias players, numpanel inicial 5 , false si es respuesta*/
        //paneler.getPanels().get(MeetingSituationLogic.A_PANELINICI).setVisible(true);
        //paneler.get
        //setVisible(true);
        if (tipoMain != 0) {
            //paneler.getPanels().get(MeetingSituationLogic.A_PANELINICI).setVisible(true);
            //setVisible(true);

            client.setResp(false); /*quien lanza goin es el que ataca al otro player
                                   * mediante pulsar tecla o lo que sea...el otro entrara via listener*/

            EventGoInInteracction evt = new EventGoInInteracction(serverGame.getPartidaGetAlias(0), MeetingSituationLogic.A_PANELINICI, client.isResp());
            System.out.println("El evento goin se lanza cuando player 2 lo manda....");
            logger.info("sending event GoIn:" + evt);
            client.send(evt);

        }
        while (glCanvas == null || impl.startTime == 0);

        // force a resize to ensure proper canvas size.
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() + 1);
        glCanvas.setSize(glCanvas.getWidth(), glCanvas.getHeight() - 1);
    }

    protected Canvas getGlCanvas() {
        if (glCanvas == null) {

            // -------------GL STUFF------------------

            // make the canvas:
            DisplaySystem display = DisplaySystem.getDisplaySystem(LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER);
            display.registerCanvasConstructor("AWT", LWJGLAWTCanvasConstructor.class);
            glCanvas = (Canvas) display.createCanvas(width, height);

            // add a listener... if window is resized, we can do something about it.
            glCanvas.addComponentListener(new ComponentAdapter() {

                @Override
                public void componentResized(ComponentEvent ce) {
                    impl.resizeCanvas(glCanvas.getSize().width, glCanvas.getSize().height);
                }
            });
            glCanvas.addFocusListener(new FocusListener() {

                public void focusGained(FocusEvent arg0) {
                    ((AWTKeyInput) KeyInput.get()).setEnabled(true);
                    ((AWTMouseInput) MouseInput.get()).setEnabled(true);
                }

                public void focusLost(FocusEvent arg0) {
                    ((AWTKeyInput) KeyInput.get()).setEnabled(false);
                    ((AWTMouseInput) MouseInput.get()).setEnabled(false);
                }
            });

            // We are going to use jme's Input systems, so enable updating.
            ((JMECanvas) glCanvas).setUpdateInput(true);

            KeyInput.setProvider(InputSystem.INPUT_SYSTEM_AWT);
            ((AWTKeyInput) KeyInput.get()).setEnabled(false);
            KeyListener kl = (KeyListener) KeyInput.get();

            glCanvas.addKeyListener(kl);

            AWTMouseInput.setup(glCanvas, true);

            // Important!  Here is where we add the guts to the canvas:

            ((JMECanvas) glCanvas).setImplementor(impl);

            // -----------END OF GL STUFF-------------
        }
        return glCanvas;
    }
// protected void update() {
//      impl.simpleUpdate();
//    }

    protected void setupcavas() {

        impl.simpleSetup();
    }

//    public void setListenerInt(EventGoInListener listenerInt) {
//        this.GoInListener = listenerInt;
//    }

    /**
     * @return the PanelListener
     */
//    public EventPanelsInteractionTwoPlayersListener getPanelListener() {
//        return PanelListener;
//    }

    /**
     * @param PanelListener the PanelListener to set
     */
    public void setPanelListener(EventPanelsInteractionTwoPlayersListener PanelListener) {
        this.panelListener = PanelListener;
    }

    protected void startGame() {
        
        impl  = new MeetingSituationLogic(height, width, client);

        mainPanel = new JPanel();     /*panel principal*/
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBounds(0, 0, width, height);
        paneler = new MeetingSituationLogic(width, height,client);

        /*recupero el panel que previamente ha sido preparado
         * no se si habria una manera mejor de hacerlo...*/
        mainPanel.add((Component) paneler.getSuitablePanelIni(MeetingSituationLogic.A_PANELINICI, null, serverGame), BorderLayout.SOUTH);

        //paneler.getPanels().get(client.getKindPanel()).setVisible(true);
        JPanel InteracctionPanel = new JPanel();     /*panel de graficos*/
        InteracctionPanel.setPreferredSize(new Dimension(100, 100));
        InteracctionPanel.setMinimumSize(new Dimension(100, 100));
        mainPanel.add(InteracctionPanel, BorderLayout.CENTER);
        InteracctionPanel.setLayout(new BorderLayout());
        InteracctionPanel.add(getGlCanvas(), BorderLayout.CENTER);
        InteracctionPanel.setBorder(new TitledBorder(null, "JUEGO",
                TitledBorder.DEFAULT_JUSTIFICATION,
                TitledBorder.DEFAULT_POSITION, null, null));

        JScrollPane scrollPane = new JScrollPane(mainPanel);
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        // center the frame
        setLocationRelativeTo(null);
        // show frame
        //paneler.getPanels().get(MeetingSituationLogic.A_PANELINICI).setVisible(false);
        setVisible(true);


    }

    private void changePanel(int accio,boolean resp, String Options,Pont po){
        int currentPanel = paneler.getCurrentPanelId();
        paneler.getSuitablePanelIni(accio, Options, po);
        mainPanel.remove((Component)this.paneler.getPanels().get(currentPanel));
        logger.info("Old panel: " + currentPanel + ", Current panel:  " + paneler.getCurrentPanelId());
        mainPanel.add((Component)this.paneler.getPanels().get(paneler.getCurrentPanelId()), BorderLayout.SOUTH);
//        this.mainPanel.repaint();
//        this.repaint();
        this.setSize(this.getSize().width+1,this.getSize().height+1);
        this.setSize(this.getSize().width-1,this.getSize().height-1);
    }

    /*

    public Dimension getMinimumrSize() {
    return MIN_DIMENSION;
    }
     */



}
